﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;

namespace pshcli
{
    //global configuration information
    public class GlobalSettings
    {

        public string dwarfdir = "";       //E.g. DWARF_DIR=E:\CURRENT_DWARFS\Dwarfs2\
        public string xmlconfigfile = "";

        public GlobalSettings(string dwarfdir)
        {
            this.dwarfdir = dwarfdir;
            xmlconfigfile = dwarfdir + "dwarfconfig.xml";
            if (!System.IO.File.Exists(xmlconfigfile))
            {
                DwarfBench.glog.WriteLog("GlobalSettings", "ERROR: Cannot read " + xmlconfigfile);
                throw new Exception("ERROR: Dwarf config file (dwarfconfig.xml) does not exist.");
            }
            else
            {
                ReadXmlFile(xmlconfigfile);
            }
        }

        //global settings4
        public string excludelist = "";
        public int proctimeout = 0;
        public int jobtimeout = 0;
        public string inputdirectory = "";
        public string inputfilesmall = "";
        public string inputfilemedium = "";
        public string inputfilelarge = "";
        public string profiledirectory = "";
        public string profilefile = "";
        public string resultdirectory = "";
        public string resultfile = "";
        public string commandstr = "";
        public int threadcount;
        public int mpiproccount;
        public string hpcscheduler = "";
        public string mpiexecstr = "";
        public string deploymentdir = ""; //local deployment directory
        public string sdeploymentdir = ""; //(network) shared deployment directory
        public string nodelocaltargetdir = ""; //binplace directory on each compute node
        public bool mpitracingenabled = false;
        public bool xperftracingenabled = false;
        public string excelresultfile = "";
        public string excelpath = "";
        public string vampirbin = "";
        public string jumpshotpath = "";
        public string xperfviewpath = "";
        public string javabin = "";

        public string xperfcounterselect = "";
        public string mpicounterselect = "";

        public string dbclusterscriptsdir = "";

        public bool runoncluster; //this corresponds to -Cluster
        public string cluster_resource_alloc_level = "";

        private void ReadXmlFile(string xmlconfigfile)
        {

            DwarfBench.glog.WriteLog("ReadXmlFile", "Reading gsettings file " + xmlconfigfile);
            XmlDocument config = new XmlDocument();
            config.Load(xmlconfigfile);
            XmlNode node = config.DocumentElement;

            #region xpaths
            string xexcludelist = "/DwarfConfig/DwarfBench/ExcludeList";

            string xinputdirectory = "/DwarfConfig/DwarfBench/Input/InputDirectory";
            string xinputfilesmall = "/DwarfConfig/DwarfBench/Input/Small";
            string xinputfilemedium = "/DwarfConfig/DwarfBench/Input/Medium";
            string xinputfilelarge = "/DwarfConfig/DwarfBench/Input/Large";
            string xprofiledirectory = "/DwarfConfig/DwarfBench/Output/ProfileDirectory";
            string xprofilefile = "/DwarfConfig/DwarfBench/Output/ProfileFileName";
            string xresultdirectory = "/DwarfConfig/DwarfBench/Output/ResultDirectory";
            string xresultfile = "/DwarfConfig/DwarfBench/Output/ResultFileName";

            string xproctimeout = "/DwarfConfig/DwarfBench/Execution/ProcTimeOut";
            string xjobtimeout = "/DwarfConfig/DwarfBench/Execution/ClusterJobTimeOut";
            string xcommandstr = "/DwarfConfig/DwarfBench/Execution/CommandArguments";

            string xnodelocaltargetdir = "/DwarfConfig/DwarfBench/Execution/NodeLocalDeploymentDir";
            string xdeploymentdir = "/DwarfConfig/DwarfBench/Execution/LocalDeploymentDir";
            string xsdeploymentdir = "/DwarfConfig/DwarfBench/Execution/SharedDeploymentDir";

            string xthreadcount = "/DwarfConfig/DwarfBench/Execution/OpenMP/ThreadCount";
            string xmpiproccount = "/DwarfConfig/DwarfBench/Execution/MPI/ProcCount";

            string xscheduler = "/DwarfConfig/DwarfBench/Execution/MPI/Scheduler";
            string xmpiexecstr = "/DwarfConfig/DwarfBench/Execution/MPI/MpiExecStr";

            string xexcelresultfile = "/DwarfConfig/DwarfBench/Execution/Excel/ExcelResultFile";
            string xecelpath = "/DwarfConfig/DwarfBench/Execution/Excel/ExcelPath";

            string xmpitrace = "/DwarfConfig/DwarfBench/Execution/MPI/TraceEnabled";
            string xxtrace = "/DwarfConfig/DwarfBench/Execution/Xperf/TraceEnabled";

            string xvampirbin = "/DwarfConfig/DwarfBench/Execution/MPI/VampirBin";
            string xjavabin = "/DwarfConfig/DwarfBench/Execution/MPI/JumpShot/JavaBin";
            string xjumpshotpath = "/DwarfConfig/DwarfBench/Execution/MPI/JumpShot/JumpShotPath";
            string xxperfviewpath = "/DwarfConfig/DwarfBench/Execution/Xperf/XperfPath";

            string xxperfcounterselect = "/DwarfConfig/DwarfBench/Execution/Xperf/XperfArgs";
            string xmpicounterselect = "/DwarfConfig/DwarfBench/Execution/MPI/MpiTrace";
            #endregion

            string ccpdata = "";
            try
            {
                ccpdata = Environment.GetEnvironmentVariable("CCP_DATA");
                if (ccpdata != null)
                    ccpdata = ccpdata.Trim();
            }
            catch (Exception)
            { }


            nodelocaltargetdir = node.SelectSingleNode(xnodelocaltargetdir).InnerText;

            if (String.IsNullOrEmpty(nodelocaltargetdir))
            {
                nodelocaltargetdir = ccpdata + "SpoolDir";
            }
            else
            {
                nodelocaltargetdir = nodelocaltargetdir.Trim();
            }

            deploymentdir = node.SelectSingleNode(xdeploymentdir).InnerText;
            if (String.IsNullOrEmpty(deploymentdir))
            {
                deploymentdir = Environment.GetEnvironmentVariable("DWARF_DIR");
                if (deploymentdir != null)
                    deploymentdir = deploymentdir.Trim();
            }
            else
            {
                deploymentdir = deploymentdir.Trim();
            }

            sdeploymentdir = node.SelectSingleNode(xsdeploymentdir).InnerText;
            if (String.IsNullOrEmpty(sdeploymentdir))
            {
                sdeploymentdir = Environment.GetEnvironmentVariable("DWARF_SHARE_DIR");
                if (sdeploymentdir != null)
                    sdeploymentdir = sdeploymentdir.Trim();
            }
            else
            {
                sdeploymentdir = sdeploymentdir.Trim();
            }

            dbclusterscriptsdir = Environment.GetEnvironmentVariable("DWARF_SHARE_DIR");
            if (!String.IsNullOrEmpty(dbclusterscriptsdir))
            {
                dbclusterscriptsdir = dbclusterscriptsdir.Trim();
                dbclusterscriptsdir += "Scripts\\ClusterScripts\\";
            }


            excludelist = node.SelectSingleNode(xexcludelist).InnerText;
            if (!String.IsNullOrEmpty(excludelist))
            {
                excludelist = excludelist.Trim();
            }

            string _proctimeout = node.SelectSingleNode(xproctimeout).InnerText;
            Int32.TryParse(_proctimeout, out proctimeout);
            if (proctimeout <= 0)
                proctimeout = 172800000; //max runtime is 48hours

            string _jobtimeout = node.SelectSingleNode(xjobtimeout).InnerText;
            Int32.TryParse(_jobtimeout, out jobtimeout);
            if (jobtimeout <= 0)
                jobtimeout = 172800000; //max runtime is 48housr

            inputdirectory = node.SelectSingleNode(xinputdirectory).InnerText;
            inputfilesmall = node.SelectSingleNode(xinputfilesmall).InnerText;
            inputfilemedium = node.SelectSingleNode(xinputfilemedium).InnerText;
            inputfilelarge = node.SelectSingleNode(xinputfilelarge).InnerText;
            profiledirectory = node.SelectSingleNode(xprofiledirectory).InnerText;
            profilefile = node.SelectSingleNode(xprofilefile).InnerText;
            resultdirectory = node.SelectSingleNode(xresultdirectory).InnerText;
            resultfile = node.SelectSingleNode(xresultfile).InnerText;
            commandstr = node.SelectSingleNode(xcommandstr).InnerText;

            if (!String.IsNullOrEmpty(inputdirectory)) inputdirectory = inputdirectory.Trim();
            if (!String.IsNullOrEmpty(inputfilesmall)) inputfilesmall = inputfilesmall.Trim();
            if (!String.IsNullOrEmpty(inputfilemedium)) inputfilemedium = inputfilemedium.Trim();
            if (!String.IsNullOrEmpty(inputfilelarge)) inputfilelarge = inputfilelarge.Trim();
            if (!String.IsNullOrEmpty(profiledirectory)) profiledirectory = profiledirectory.Trim();
            if (!String.IsNullOrEmpty(profilefile)) profilefile = profilefile.Trim();
            if (!String.IsNullOrEmpty(resultdirectory)) resultdirectory = resultdirectory.Trim();
            if (!String.IsNullOrEmpty(commandstr)) commandstr = commandstr.Trim();

            int.TryParse(node.SelectSingleNode(xthreadcount).InnerText, out threadcount);

            int.TryParse(node.SelectSingleNode(xmpiproccount).InnerText, out mpiproccount);

            hpcscheduler = node.SelectSingleNode(xscheduler).InnerText;
            if (String.IsNullOrEmpty(hpcscheduler))
            {
                try
                {
                    hpcscheduler = Environment.GetEnvironmentVariable("CCP_SCHEDULER");
                    if (hpcscheduler != null)
                        hpcscheduler = hpcscheduler.Trim();
                }
                catch (Exception)
                {
                    DwarfBench.glog.WriteLog("ReadXmlFile", "%CCP_SCHEDULER% is not set.");
                }
            }
            else
            {
                hpcscheduler = hpcscheduler.Trim();
            }


            mpiexecstr = node.SelectSingleNode(xmpiexecstr).InnerText;

            if (!string.IsNullOrEmpty(mpiexecstr)) mpiexecstr = mpiexecstr.Trim();

            if (String.Compare("yes", node.SelectSingleNode(xmpitrace).InnerText.ToLower()) == 0)
                mpitracingenabled = true;
            if (String.Compare("yes", node.SelectSingleNode(xxtrace).InnerText.ToLower()) == 0)
                xperftracingenabled = true;

            excelresultfile = node.SelectSingleNode(xexcelresultfile).InnerText;
            if (!string.IsNullOrEmpty(excelresultfile)) excelresultfile = excelresultfile.Trim();

            var ddir = System.Environment.GetEnvironmentVariable("DWARF_DIR");
            if (ddir != null) ddir = ddir.Trim(); else ddir = "";
            excelresultfile = excelresultfile.Replace("%DWARF_DIR%", ddir);

            excelpath = node.SelectSingleNode(xecelpath).InnerText;
            if (!String.IsNullOrEmpty(excelpath)) excelpath = excelpath.Trim();

            vampirbin = node.SelectSingleNode(xvampirbin).InnerText;
            if (!String.IsNullOrEmpty(vampirbin)) vampirbin = vampirbin.Trim();

            jumpshotpath = node.SelectSingleNode(xjumpshotpath).InnerText;
            if (!String.IsNullOrEmpty(jumpshotpath)) jumpshotpath = jumpshotpath.Trim();

            xperfviewpath = node.SelectSingleNode(xxperfviewpath).InnerText;
            if (!String.IsNullOrEmpty(xperfviewpath)) xperfviewpath = xperfviewpath.Trim();

            javabin = node.SelectSingleNode(xjavabin).InnerText;
            if (!String.IsNullOrEmpty(javabin)) javabin = javabin.Trim();

            mpicounterselect = node.SelectSingleNode(xmpicounterselect).InnerText;
            if (!String.IsNullOrEmpty(mpicounterselect)) mpicounterselect = mpicounterselect.Trim();

            xperfcounterselect = node.SelectSingleNode(xxperfcounterselect).InnerText;
            if (!String.IsNullOrEmpty(xperfcounterselect)) xperfcounterselect = xperfcounterselect.Trim();

            DwarfBench.glog.WriteLog("ReadXmlFile", "Xml settings read successfully:");
            DwarfBench.glog.WriteLog("ReadXmlFile", "clusterscripts" + dbclusterscriptsdir);
            DwarfBench.glog.WriteLog("ReadXmlFile", "excludelist: " + excludelist);
            DwarfBench.glog.WriteLog("ReadXmlFile", "proctimeout: " + proctimeout);
            DwarfBench.glog.WriteLog("ReadXmlFile", "deploymentdir (local): " + deploymentdir);
            DwarfBench.glog.WriteLog("ReadXmlFile", "deploymentdir (shared): " + sdeploymentdir);
            DwarfBench.glog.WriteLog("ReadXmlFile", "inputdirectory: " + inputdirectory);
            DwarfBench.glog.WriteLog("ReadXmlFile", "inputfilesmall: " + inputfilesmall);
            DwarfBench.glog.WriteLog("ReadXmlFile", "inputfilemedium: " + inputfilemedium);
            DwarfBench.glog.WriteLog("ReadXmlFile", "inputfilelarge: " + inputfilelarge);
            DwarfBench.glog.WriteLog("ReadXmlFile", "profiledirectory: " + profiledirectory);
            DwarfBench.glog.WriteLog("ReadXmlFile", "profilefile: " + profilefile);
            DwarfBench.glog.WriteLog("ReadXmlFile", "resultdirectory: " + resultdirectory);
            DwarfBench.glog.WriteLog("ReadXmlFile", "resultdirectory: " + resultdirectory);
            DwarfBench.glog.WriteLog("ReadXmlFile", "resultfile: " + resultfile);
            DwarfBench.glog.WriteLog("ReadXmlFile", "threadcount: " + threadcount);

            DwarfBench.glog.WriteLog("ReadXmlFile", "mpiproccount: " + mpiproccount);
            DwarfBench.glog.WriteLog("ReadXmlFile", "hpcscheduler: " + hpcscheduler);

            DwarfBench.glog.WriteLog("ReadXmlFile", "mpiexecstr: " + mpiexecstr);
            DwarfBench.glog.WriteLog("ReadXmlFile", "mpitracingenabled: " + mpitracingenabled);
            DwarfBench.glog.WriteLog("ReadXmlFile", "xperftracingenabled: " + xperftracingenabled);
            DwarfBench.glog.WriteLog("ReadXmlFile", "excelresultfile: " + excelresultfile);

            DwarfBench.glog.WriteLog("ReadXmlFile", "excelpath: " + excelpath);
            DwarfBench.glog.WriteLog("ReadXmlFile", "vampirbin: " + vampirbin);
            DwarfBench.glog.WriteLog("ReadXmlFile", "jumpshotpath: " + jumpshotpath);
            DwarfBench.glog.WriteLog("ReadXmlFile", "xperfviewpath: " + xperfviewpath);
            DwarfBench.glog.WriteLog("ReadXmlFile", "javabin: " + javabin);

            DwarfBench.glog.WriteLog("ReadXmlFile", "xperfcounterselect: " + xperfcounterselect);
            DwarfBench.glog.WriteLog("ReadXmlFile", "mpicounterselect: " + mpicounterselect);

        }

    }
}